package com.hrs.core.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hrs.common.doMain.PageResultDto;
import com.hrs.common.enums.Status;
import com.hrs.common.exception.GlobalException;
import com.hrs.common.result.CodeMsg;
import com.hrs.common.result.Result;
import com.hrs.core.mapper.DepartmentMapper;
import com.hrs.core.mapper.PositionMapper;
import com.hrs.core.service.DepartmentService;
import com.hrs.core.service.PositionService;
import com.hrs.core.service.SalaryScaleService;
import com.hrs.enity.db.Achieve;
import com.hrs.core.service.AchieveService;
import com.hrs.core.mapper.AchieveMapper;
import com.hrs.enity.db.Department;
import com.hrs.enity.db.Position;
import com.hrs.enity.db.SalaryScale;
import com.hrs.enity.dto.AchieveAddDto;
import com.hrs.enity.dto.AchieveUpdateDto;
import com.hrs.enity.dto.AchieveViewDto;
import com.hrs.enity.ro.AchievePageRo;
import com.hrs.enity.vo.DepartmentIdVo;
import com.hrs.util.PageUtil;
import com.hrs.util.RedisIdWorker;
import com.hrs.util.RequestUserUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;

/**
* @author 纱雾休比酱
* @description 针对表【t_achieve(档案表)】的数据库操作Service实现
* @createDate 2022-12-05 23:04:48
*/
@Slf4j
@Service
public class AchieveServiceImpl extends ServiceImpl<AchieveMapper, Achieve>
    implements AchieveService {

    @Autowired
    private AchieveMapper achieveMapper;
    @Autowired
    private RedisIdWorker redisIdWorker;
    @Autowired
    private PositionService positionService;
    @Autowired
    private SalaryScaleService salaryScaleService;
    @Autowired
    private DepartmentService departmentService;
    @Autowired
    private DepartmentMapper departmentMapper;
    @Autowired
    private PositionMapper positionMapper;

    /**
     * 插入一条档案记录
     * @param achieveAddDto
     * @return
     */
    @Override
    public Result<String> add(AchieveAddDto achieveAddDto) {
        Achieve achieve = new Achieve();
        BeanUtils.copyProperties(achieveAddDto,achieve);

        //生成id:年份（4位）+ 一级结构编号（2位）+ 二级机构编号（2位）+ 三级机构编号（2位）+ 编号（2位）
        long id = 0L;
        //1.年份
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        id += year;
        //2.机构编号
        DepartmentIdVo dIds = achieveMapper.getIds(achieveAddDto.getDepartmentId());
        if(Objects.isNull(dIds)) {
            return Result.error("机构不存在");
        }
        if(dIds.getLevelI() == null || dIds.getLevelII() == null || dIds.getLevelIII() == null){
            return Result.error("机构不存在");
        }
        id = id * 100 + dIds.getLevelI() % 100;
        id = id * 100 + dIds.getLevelII() % 100;
        id = id * 100 + dIds.getLevelIII() % 100;
        //3.编号，利用redis自增长
        id = id * 100 + redisIdWorker.nextId("aid",year);
        achieve.setId(id);

        checkIsExist(achieve.getPositionId(),achieve.getSalaryScaleId(),achieve.getDepartmentId());

        //插入登记人id
        achieve.setRegistrationId(RequestUserUtil.getRequestUserId());

        achieve.setStatus(Status.WAITING);

        this.save(achieve);
        return Result.success();
    }

    /**
     * 档案复核
     * @return
     */
    @Override
    public Result<String> review(AchieveUpdateDto achieveUpdateDto) {
        Long id = achieveUpdateDto.getId();
        Achieve achieve = this.getById(id);
        if(Objects.isNull(achieve)) {
            return Result.error("对象不存在");
        }
        int key = achieve.getStatus().getKey();
        if(key != Status.WAITING.getKey()) {
            return Result.error("非待复核状态");
        } else if(key == Status.DELETED.getKey()) {
            return Result.success("档案处于“已删除”状态");
        }

        BeanUtils.copyProperties(achieveUpdateDto,achieve);
        achieve.setDepartmentId(null);

        checkIsExist(achieve.getPositionId(),achieve.getSalaryScaleId(),null);

        //插入复核人id
        achieve.setReviewId(RequestUserUtil.getRequestUserId());

        //插入复核时间
        achieve.setReviewTime(LocalDateTime.now());

        //更新档案状态
        achieve.setStatus(Status.NORMAL);

        //更新
        this.updateById(achieve);

        return Result.success();
    }

    /**
     * 根据id获取一条档案信息
     * @param id
     * @return
     */
    @Override
    public Result<AchieveViewDto> get(Long id) {
        return Result.success(achieveMapper.get(id));
    }

    public void checkIsExist(Integer positionId, Long salaryScaleId,Integer deptId){
        //判断职位id是否存在
        Position position = positionService.getById(positionId);
        if(Objects.isNull(position)){
            throw new GlobalException(new CodeMsg("该职位不存在"));
        }

        //判断薪酬id是否存在
        SalaryScale salaryScale = salaryScaleService.getById(salaryScaleId);
        if(Objects.isNull(salaryScale)){
            throw new GlobalException(new CodeMsg("该薪酬标准不存在"));
        }

        //判断部门是否存在
        if(deptId != null) {
            Department department = departmentService.getById(deptId);
            if(Objects.isNull(department)) {
                throw new GlobalException(new CodeMsg("该部门不存在"));
            }
        }
    }

    @Override
    public Result<String> updateAchieve(AchieveUpdateDto achieveUpdateDto) {
        Long id = achieveUpdateDto.getId();
        Achieve achieve = this.getById(id);
        if(Objects.isNull(achieve)) {
            return Result.error("对象不存在");
        }
        int key = achieve.getStatus().getKey();
        if(key != Status.NORMAL.getKey()) {
            return Result.error("非正常状态");
        } else if(key == Status.DELETED.getKey()) {
            return Result.success("档案处于“已删除”状态");
        }

        checkIsExist(achieveUpdateDto.getPositionId(),achieveUpdateDto.getSalaryScaleId(),null);
        BeanUtils.copyProperties(achieveUpdateDto,achieve);
        achieve.setDepartmentId(null);

        //插入变更人
        achieve.setChangeId(RequestUserUtil.getRequestUserId());
        //插入变更时间
        achieve.setChangeTime(LocalDateTime.now());

        achieve.setStatus(Status.WAITING);
        this.updateById(achieve);
        return Result.success();
    }

    @Override
    public Result<PageResultDto<AchieveViewDto>> pageAchieve(AchievePageRo achievePageRo) {
        //组装机构条件
        Set<Integer> deptIds = null;
        Integer deptI = achievePageRo.getDeptI();
        Integer deptII = achievePageRo.getDeptII();
        Integer deptIII = achievePageRo.getDeptIII();
        if(deptIII != null) {
            deptIds = new HashSet<>();
            deptIds.add(deptIII);
        } else {
            if(deptI != null) {
                deptIds = departmentMapper.selectDeptIds(deptI,deptII);
                if(deptIds.size() == 0) {
                    return Result.success(new PageResultDto<>());
                }
            }
        }

        //组装职位条件
        Set<Integer> positionIds = null;
        Integer pType = achievePageRo.getPType();
        Integer pName = achievePageRo.getPName();
        if(pType != null) {
            positionIds = positionMapper.selectPositionIds(pType, pName);
            if(positionIds.size() == 0) {
                positionIds = null;
            }
        }

        Date begin= achievePageRo.getBeginTime();
        Date end= achievePageRo.getEndTime();
        if(begin == null || end == null) {
            begin = null;
            end = null;
        }

        Integer pageNum = achievePageRo.getPageNum();
        Integer pageSize = achievePageRo.getPageSize();
        Status status = achievePageRo.getStatus();
        List<AchieveViewDto> achieveViewDtos =  achieveMapper.pageAchieve((pageNum - 1) * pageSize,pageSize,
                deptIds != null ? new ArrayList<>(deptIds) : null,
                positionIds != null ? new ArrayList<>(positionIds) : null,begin,end,
                status != null ? status.getKey() : null);
        Long total = achieveMapper.totalPage(deptIds != null ? new ArrayList<>(deptIds) : null, positionIds != null ?
                new ArrayList<>(positionIds) : null, begin, end, status != null ? status.getKey() : null);

        PageResultDto<AchieveViewDto> resultDto = PageUtil.convert2PageResult(pageNum, pageSize,
                achieveViewDtos, total);

        return Result.success(resultDto);
    }

    @Override
    public Result<String> delete(Long id) {
        boolean update =
                this.lambdaUpdate().set(Achieve::getStatus, Status.DELETED).eq(Achieve::getId, id).eq(Achieve::getStatus, Status.NORMAL).update();
        if(!update) {
            return Result.error("删除失败，请检查档案是否处于待复核或已删除状态");
        }
        return Result.success();
    }

    @Override
    public Result<String> recoverAchieve(Long id) {
        boolean update =
                this.lambdaUpdate().set(Achieve::getStatus, Status.NORMAL).eq(Achieve::getId, id).eq(Achieve::getStatus, Status.DELETED).update();
        if(!update){
            return Result.error("恢复失败，请检查档案是否处于已删除状态");
        }
        return Result.success();
    }
}




